package mobile

import (
	"callsips/internal/utils"
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"strings"
	"time"
)

var _ YunhuMobileModel = (*customYunhuMobileModel)(nil)

type (
	// YunhuMobileModel is an interface to be customized, add more methods here,
	// and implement the added methods in customYunhuMobileModel.
	YunhuMobileModel interface {
		yunhuMobileModel
		ChangeQuickBind(ctx context.Context, id int64, phone string, bindNum int64) error
		RestBindNum(ctx context.Context, phoneIds []int64, phone []string) error // 绑定座席
		IsRealPhone(ctx context.Context, phoneIds []int64, value int64) error    // 标记实名
		RestoryBatch(ctx context.Context, phoneIds []int64) error                // 批量销户
		DeleteBatch(ctx context.Context, phoneIds []int64) error                 // 批量删除
		RemarkBatch(ctx context.Context, phoneIds []int64, remark string) error
		ListByids(ctx context.Context, phoneIds []int64) ([]*YunhuMobile, error)
		List(ctx context.Context, customerId int64, agentId int64, cityId int64, phone string, isReal int64, isBind int64, carrierId int64, isDel int64, page int64, pagesize int64) ([]*YunhuMobile, error)
		Count(ctx context.Context, customerId int64, agentId int64, cityId int64, phone string, isReal int64, isBind int64, arrierId int64, isDel int64) (int64, error)
		AccountStatistics(ctx context.Context, customerId int64) ([]*AccountStatistics, error)
	}

	AccountStatistics struct {
		AccountId int64 `db:"account_id"`
		Total     int64 `db:"total"`
	}

	customYunhuMobileModel struct {
		*defaultYunhuMobileModel
	}
)

func (m *customYunhuMobileModel) RestBindNum(ctx context.Context, phoneIds []int64, phone []string) error {
	var pids []string = utils.IntArrToStringArr(phoneIds)
	var cacheKey []string = make([]string, 0)
	for key, val := range pids {
		cacheKey = append(cacheKey, fmt.Sprintf("%s%s", cacheYunhuMobileIdPrefix, val))
		cacheKey = append(cacheKey, fmt.Sprintf("%s%v", cacheYunhuMobilePhonePrefix, phone[key]))
	}

	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set bind_num = 0,is_bind = 1  where `id` in(%s)", m.table, strings.Join(pids, ","))
		return conn.ExecCtx(ctx, query)
	}, cacheKey...)

	return err
}

func (m *customYunhuMobileModel) ChangeQuickBind(ctx context.Context, id int64, phone string, bindNum int64) error {
	yunhuMobileIdKey := fmt.Sprintf("%s%v", cacheYunhuMobileIdPrefix, id)
	yunhuMobilePhoneKey := fmt.Sprintf("%s%v", cacheYunhuMobilePhonePrefix, phone)
	var isBind int64 = 1
	if bindNum > 0 {
		isBind = 2
	}
	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set `bind_num` = ?,`is_bind` = ? where `id` = ?", m.table)
		return conn.ExecCtx(ctx, query, bindNum, isBind, id)
	}, yunhuMobileIdKey, yunhuMobilePhoneKey)

	return err
}

func (m *customYunhuMobileModel) RemarkBatch(ctx context.Context, phoneIds []int64, remark string) error {
	var pids []string = utils.IntArrToStringArr(phoneIds)
	var cacheKey []string = make([]string, len(pids))
	for k, val := range pids {
		cacheKey[k] = fmt.Sprintf("%s%s", cacheYunhuMobileIdPrefix, val)
	}

	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set remark = ?  where `id` in(%s)", m.table, strings.Join(pids, ","))
		return conn.ExecCtx(ctx, query, remark)
	}, cacheKey...)

	return err
}

// 标记实名
func (m *customYunhuMobileModel) IsRealPhone(ctx context.Context, phoneIds []int64, value int64) error {
	var pids []string = utils.IntArrToStringArr(phoneIds)
	var cacheKey []string = make([]string, len(pids))
	for k, val := range pids {
		cacheKey[k] = fmt.Sprintf("%s%s", cacheYunhuMobileIdPrefix, val)
	}

	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set is_real = ?,real_time = ?  where `id` in(%s)", m.table, strings.Join(pids, ","))
		return conn.ExecCtx(ctx, query, value, time.Now().Unix())
	}, cacheKey...)

	return err
}

// 批量销户
func (m *customYunhuMobileModel) RestoryBatch(ctx context.Context, phoneIds []int64) error {
	var pids []string = utils.IntArrToStringArr(phoneIds)
	var cacheKey []string = make([]string, len(pids))
	for k, val := range pids {
		cacheKey[k] = fmt.Sprintf("%s%s", cacheYunhuMobileIdPrefix, val)
	}

	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set is_del = 2 where `id` in(%s)", m.table, strings.Join(pids, ","))
		return conn.ExecCtx(ctx, query)
	}, cacheKey...)

	return err
}

// 批量删除
func (m *customYunhuMobileModel) DeleteBatch(ctx context.Context, phoneIds []int64) error {
	var pids []string = utils.IntArrToStringArr(phoneIds)
	var cacheKey []string = make([]string, len(pids))
	for k, val := range pids {
		cacheKey[k] = fmt.Sprintf("%s%s", cacheYunhuMobileIdPrefix, val)
	}

	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("delete from %s where `id` in(%s)", m.table, strings.Join(pids, ","))
		return conn.ExecCtx(ctx, query)
	}, cacheKey...)

	return err
}

// 统计企业座席的手机号
func (m *customYunhuMobileModel) AccountStatistics(ctx context.Context, customerId int64) ([]*AccountStatistics, error) {
	var resp []*AccountStatistics
	var query string = fmt.Sprintf("SELECT account_id,count(id) as total FROM %s WHERE customer_id = ? AND is_del = 1", m.table)
	if err := m.QueryRowsNoCacheCtx(ctx, &resp, query, customerId); err != nil && err != ErrNotFound {
		return nil, err
	}
	return resp, nil
}

// 查询ID信息
func (m *customYunhuMobileModel) ListByids(ctx context.Context, phoneIds []int64) ([]*YunhuMobile, error) {
	var resp []*YunhuMobile
	query := fmt.Sprintf("select %s from %s where id in(%s) order by id desc", yunhuMobileRows, m.table, utils.IntArrToString(phoneIds))
	if err := m.QueryRowsNoCacheCtx(ctx, &resp, query); err != nil && err != ErrNotFound {
		return nil, err
	}

	return resp, nil
}

// 查询列表
func (m *customYunhuMobileModel) List(ctx context.Context, customerId int64, agentId int64, cityId int64, phone string, isReal int64, isBind int64, carrierId int64, isDel int64, page int64, pagesize int64) ([]*YunhuMobile, error) {
	var sqlWheres string = m.getWhere(customerId, agentId, cityId, phone, isReal, isBind, carrierId, isDel)
	var resp []*YunhuMobile
	query := fmt.Sprintf("select %s from %s %s order by id desc limit ?,?", yunhuMobileRows, m.table, sqlWheres)
	if err := m.QueryRowsNoCacheCtx(ctx, &resp, query, (page-1)*pagesize, pagesize); err != nil && err != ErrNotFound {
		return nil, err
	}

	return resp, nil
}

// 查询数量
func (m *customYunhuMobileModel) Count(ctx context.Context, customerId int64, agentId int64, cityId int64, phone string, isReal int64, isBind int64, carrierId int64, isDel int64) (int64, error) {
	var sqlWheres string = m.getWhere(customerId, agentId, cityId, phone, isReal, isBind, carrierId, isDel)
	var countTotal Counts
	var sql string = fmt.Sprintf("select count(*) as total from %s %s", m.table, sqlWheres)
	var err error = m.QueryRowNoCacheCtx(ctx, &countTotal, sql)
	return countTotal.Total, err
}

func (m *customYunhuMobileModel) getWhere(customerId int64, agentId int64, cityId int64, phone string, isReal int64, isBind int64, carrierId int64, isDel int64) string {
	var sqlWhere []string = make([]string, 0)

	if isDel > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" is_del = %d ", isDel))
	}

	if customerId > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" customer_id = %d ", customerId))
	}

	if agentId > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" agent_id = %d ", agentId))
	}

	if cityId > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" city_id = %d ", cityId))
	}

	if phone != "" {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" phone = '%s' ", phone))
	}

	if isReal > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" is_real = %d ", isReal))
	}

	if isBind > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" is_bind = %d ", isBind))
	}

	if carrierId > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" carrier_id = %d ", carrierId))
	}

	if len(sqlWhere) == 0 {
		return ""
	}

	var sqlStr string = strings.Join(sqlWhere, " and ")
	if sqlStr != "" {
		sqlStr = " where " + sqlStr
	}

	return sqlStr
}

// NewYunhuMobileModel returns a model for the database table.
func NewYunhuMobileModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) YunhuMobileModel {
	return &customYunhuMobileModel{
		defaultYunhuMobileModel: newYunhuMobileModel(conn, c, opts...),
	}
}
